简介
想和朋友联机打局域网游戏,在家需要连接到公司办公,如果是机密信息还要保证数据的加密传输,而且还要简单稳定好用,那么OpenVPN绝对是不二之选,OpenVPN是一个基于OpenSSL库的应用层VPN实现,完全开源免费,而且支持的平台众多,Linux平台,Windows平台,Android和IOS平台也都支持。
环境
想要连通两个NAT后的网络,比如家里的局域网和公司的局域网就必须存在一个公网IP来做数据中转。这里使用阿里云的一台主机来做数据中转。
系统使用的是 Ubuntu 16.04.03 64位
OpenVPN 使用最新的稳定版 2.3.18 点此下载
如果下载不了,可能需要自备梯子或者从其他地方下载。如果使用的 CentOS 系列安装可能需要先关闭 SElinux。
安装
也可以选择直接从官方仓库中下载安装使用。
解决依赖
1 | apt-get install make gcc g++ libssl-dev liblzo2-dev libpam-dev unzip |
这里只适用于 Ubuntu 系统
编译安装
1 | tar xf openvpn-2.3.18.tar.xz |
由于系统环境的复杂,配置过程中可能会缺少某些库的头文件,只需要找到这些头文件所在的包然后安装下就好了。
配置证书
服务端证书
配置easy-rsa
1 | cd /etc/openvpn |
然后编辑 vars
文件,修改下列内容的值为随意内容。需要注意的是,值不可以是空的。
export KEY_COUNTRY="US"
export KEY_PROVINCE="California"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="MyOrganizationalUnit"
我这里修改为了如下内容
export KEY_COUNTRY="CN"
export KEY_PROVINCE="BeiJing"
export KEY_CITY="BeiJing"
export KEY_ORG="wu"
export KEY_EMAIL="admin@localhost.com"
export KEY_OU="openvpn"
接着修改 export KEY_NAME="EasyRSA"
这句话,将 EasyRSA
改为自己喜欢的名字,这里就简单的使用 server
,修改后就可以保存退出了。
创建根证书
1 | source vars |
这一步一路的回车就好,因为已经在 vars
文件中配置过了。
root@ubuntu:/etc/openvpn/easy-rsa/easy-rsa/2.0# ./build-ca
Generating a 2048 bit RSA private key
............................................................+++
..........................+++
writing new private key to 'ca.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name (full name) [BeiJing]:
Locality Name (eg, city) [BeiJing]:
Organization Name (eg, company) [wu]:
Organizational Unit Name (eg, section) [openvpn]:
Common Name (eg, your name or your server's hostname) [wu CA]:
Name [server]:
Email Address [admin@localhost.com]:
颁发服务端证书
1 | ./build-key-server server |
这个 server
就是刚才 export KEY_NAME="EasyRSA"
中指定的名字。之后就是一路的回车,当遇到两个问答的时候都回答 y
就可以了。
root@ubuntu:/etc/openvpn/easy-rsa/easy-rsa/2.0# ./build-key-server server
Generating a 2048 bit RSA private key
.......................+++
..............+++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name (full name) [BeiJing]:
Locality Name (eg, city) [BeiJing]:
Organization Name (eg, company) [wu]:
Organizational Unit Name (eg, section) [openvpn]:
Common Name (eg, your name or your server's hostname) [server]:
Name [server]:
Email Address [admin@localhost.com]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/easy-rsa/2.0/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'CN'
stateOrProvinceName :PRINTABLE:'BeiJing'
localityName :PRINTABLE:'BeiJing'
organizationName :PRINTABLE:'wu'
organizationalUnitName:PRINTABLE:'openvpn'
commonName :PRINTABLE:'server'
name :PRINTABLE:'server'
emailAddress :IA5STRING:'admin@localhost.com'
Certificate is to be certified until Apr 30 07:50:21 2028 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
生成Diffie-Hellman文件
Diffie-Hellman是一种确保共享KEY安全穿越不安全网络的方法
1 | ./build-dh |
这一步需要的时间会长一些。
客户端证书
颁发客户端证书
使用 build-key
命令可以颁发一个不带密码的证书,如果需要带密码保护的证书,可以使用 build-key-pass
命令。这里使用不带密码的凭证,证书名为 client1
1 | ./build-key client1 |
同理 一路回车后最后两个问答输入 y
root@ubuntu:/etc/openvpn/easy-rsa/easy-rsa/2.0# ./build-key client1
Generating a 2048 bit RSA private key
....................+++
..............................+++
writing new private key to 'client1.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name (full name) [BeiJing]:
Locality Name (eg, city) [BeiJing]:
Organization Name (eg, company) [wu]:
Organizational Unit Name (eg, section) [openvpn]:
Common Name (eg, your name or your server's hostname) [client1]:
Name [server]:
Email Address [admin@localhost.com]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /etc/openvpn/easy-rsa/easy-rsa/2.0/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'CN'
stateOrProvinceName :PRINTABLE:'BeiJing'
localityName :PRINTABLE:'BeiJing'
organizationName :PRINTABLE:'wu'
organizationalUnitName:PRINTABLE:'openvpn'
commonName :PRINTABLE:'client1'
name :PRINTABLE:'server'
emailAddress :IA5STRING:'admin@localhost.com'
Certificate is to be certified until Apr 30 07:58:09 2028 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
安置证书
现在所有的证书都在 keys
目录中,为了方便使用,将 keys
目录直接软链到 /etc/openvpn/
下
1 | ln -s /etc/openvpn/easy-rsa/easy-rsa/2.0/keys/ /etc/openvpn/keys |
到这里,安装的部分就结束了。
使用
服务端配置
配置文件
编辑服务端配置文件:/etc/openvpn/server.conf
修改内容如下:
port 2001
proto udp
dev tun
ca keys/ca.crt
cert keys/server.crt
key keys/server.key
dh keys/dh2048.pem
server 10.0.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 10.0.0.0 255.255.255.0"
client-to-client
keepalive 10 120
tls-auth keys/ta.key 0
cipher AES-256-CBC
auth SHA256
key-direction 0
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status.log
verb 3
需要注意的是,这里使用 udp 的 2001 端口,在阿里云等环境,还需要配置相应的安全组策略来开放这个端口的流量。
Linux配置
开启 Linux 的内核转发功能,编辑 /etc/sysctl.conf
文件,取消掉 #net.ipv4.ip_forward=1
之前的注释。然后执行 sysctl -p
命令。
root@ubuntu:/etc/openvpn# sysctl -p
net.ipv4.ip_forward = 1
vm.swappiness = 0
net.ipv4.neigh.default.gc_stale_time = 120
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_announce = 2
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 1024
net.ipv4.tcp_synack_retries = 2
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
还需要确保 iptable 的 FORWARD
链允许数据转发
1 | iptables -P FORWARD ACCEPT |
启动OpenVPN
1 | /usr/local/openvpn/sbin/openvpn --cd /etc/openvpn/ --config /etc/openvpn/server.conf |
以调试模式启动 OpenVPN,如果启动过程中有什么错误的话会显示在输出里,确定没有问题了,可以添加 --daemon
参数在后台运行 OpenVPN
root@ubuntu:/etc/openvpn# /usr/local/openvpn/sbin/openvpn --cd /etc/openvpn/ --config /etc/openvpn/server.conf
Thu May 3 16:32:55 2018 OpenVPN 2.3.18 x86_64-unknown-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [MH] [IPv6] built on May 3 2018
Thu May 3 16:32:55 2018 library versions: OpenSSL 1.0.2g 1 Mar 2016, LZO 2.08
Thu May 3 16:32:55 2018 Diffie-Hellman initialized with 2048 bit key
Thu May 3 16:32:55 2018 Control Channel Authentication: using 'keys/ta.key' as a OpenVPN static key file
Thu May 3 16:32:55 2018 Outgoing Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Thu May 3 16:32:55 2018 Incoming Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
Thu May 3 16:32:55 2018 Socket Buffers: R=[212992->212992] S=[212992->212992]
Thu May 3 16:32:55 2018 ROUTE_GATEWAY 172.31.143.253/255.255.240.0 IFACE=eth0 HWADDR=00:16:3e:08:fb:5f
Thu May 3 16:32:55 2018 TUN/TAP device tun0 opened
Thu May 3 16:32:55 2018 TUN/TAP TX queue length set to 100
Thu May 3 16:32:55 2018 do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Thu May 3 16:32:55 2018 /sbin/ifconfig tun0 10.0.0.1 pointopoint 10.0.0.2 mtu 1500
Thu May 3 16:32:55 2018 /sbin/route add -net 10.0.0.0 netmask 255.255.255.0 gw 10.0.0.2
Thu May 3 16:32:55 2018 GID set to nogroup
Thu May 3 16:32:55 2018 UID set to nobody
Thu May 3 16:32:55 2018 UDPv4 link local (bound): [undef]
Thu May 3 16:32:55 2018 UDPv4 link remote: [undef]
Thu May 3 16:32:55 2018 MULTI: multi_init called, r=256 v=256
Thu May 3 16:32:55 2018 IFCONFIG POOL: base=10.0.0.4 size=62, ipv6=0
Thu May 3 16:32:55 2018 IFCONFIG POOL LIST
Thu May 3 16:32:55 2018 Initialization Sequence Completed
使用 ifconfig
命令,应该可以看到多出来了一块 tun0
的网卡。
制作客户端ovpn文件
为了方便客户端的连接,可以在服务端制作好客户端的配置文件,只需将文件下发给客户端,就可以直接使用了。这个文件的拓展名是 ovpn
1 | cd /etc/openvpn/ |
然后编辑 client.conf
为以下内容,其中连接服务器的 IP 需要修改为自己的。
client
dev tun
proto udp
remote 47.xxx.xxx.155 2001
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
auth SHA256
key-direction 1
verb 3
explicit-exit-notify 1
还记得刚才颁发的客户端证书 client1
吧,先为这个证书生成一份配置文件。使用一个自动化脚本来完成配置文件的创建。新建 make_config.sh
脚本,然后写入如下内容
1 |
|
开始创建
1 | chmod +x make_config.sh |
这个 client1
就是用户证书的名字,也只有存在才可以创建成功。脚本正常执行后可以在 files
目录中看到 client1.ovpn
文件,这个文件中已经包含了客户端所需要的密钥以及连接信息,所以只需要将这个文件发给用户,然后在客户端上导入就可以直接连接了。不过要注意,基于密钥的认证方式,每个密钥只允许同时一台机器连接使用。
客户端连接
首先需要将生成的 ovpn 文件发送给用户的机器上,然后还需要安装适合当前平台的客户端。
在 Linux 上登陆 OpenVPN
Linux上编译出的 openvpn
程序既可以是服务端,也可以是客户端,所以只需要再下载下来源码包编译一次就可以了。连接也非常方便,直接使用 openvpn --config client1.ovpn
即可。如果想后台运行,也只需要添加 --daemon
参数。
当连接成功后,可以看到多出来一块 tun0
的网卡
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500
inet 10.0.0.6 netmask 255.255.255.255 destination 10.0.0.5
inet6 fe80::bf9f:2316:1d8c:83d1 prefixlen 64 scopeid 0x20<link>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 100 (UNSPEC)
RX packets 1 bytes 84 (84.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5 bytes 276 (276.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
服务端IP为 10.0.0.1
,可以看看能不能PING通
root@raspberrypi:~# ping 10.0.0.1 -c 4
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=62.2 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=61.7 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=68.1 ms
64 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=68.1 ms
--- 10.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 61.782/65.097/68.185/3.103 ms
在 Windows 上登陆 OpenVPN
Windows 客户端需要在官方下载,下载时可能需要自备梯子,下载地址:点此打开
下载安装成功后,第一次打开会弹出一个窗口,说没有可以读取的配置文件,这时候只需右击系统状态栏里OpenVPN的小图标,然后选择 Import file...
打开刚才生成的 client1.ovpn
就可以了。然后再次右击小图标,点击 Connect
,等弹出的窗口自动退出口,系统也会通知 OpenVPN 是否连接成功。
在 Windows 上也是可以PING通服务器的
C:\Users\yunfwe\Desktop>ping 10.0.0.1
正在 Ping 10.0.0.1 具有 32 字节的数据:
来自 10.0.0.1 的回复: 字节=32 时间=68ms TTL=64
来自 10.0.0.1 的回复: 字节=32 时间=71ms TTL=64
来自 10.0.0.1 的回复: 字节=32 时间=62ms TTL=64
来自 10.0.0.1 的回复: 字节=32 时间=60ms TTL=64
10.0.0.1 的 Ping 统计信息:
数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
最短 = 60ms,最长 = 71ms,平均 = 65ms
在 Android 上登陆 OpenVPN
在谷歌应用商店里可以找到一款名为 openvpn-connect
的apk,使用这个软件也可以通过导入ovpn文件的方式连接到服务器。